/*
 * InfoPanel.java
 *
 * Created on 16.02.2009, 15:47:48
 */
package de.blitzcoder.collide.gui.docs;

import de.blitzcoder.collide.docs.Documentation;
import de.blitzcoder.collide.docs.Module;
import de.blitzcoder.collide.docs.Scope;
import de.blitzcoder.collide.engine.FileOpener;
import de.blitzcoder.collide.engine.parser.CodeConstant;
import de.blitzcoder.collide.engine.parser.CodeField;
import de.blitzcoder.collide.engine.parser.CodeFunction;
import de.blitzcoder.collide.engine.parser.CodeGlobal;
import de.blitzcoder.collide.engine.parser.CodeMethod;
import de.blitzcoder.collide.engine.parser.CodeObject;
import de.blitzcoder.collide.engine.parser.CodeParameter;
import de.blitzcoder.collide.engine.parser.CodeParameterObject;
import de.blitzcoder.collide.engine.parser.CodeType;
import de.blitzcoder.collide.gui.CodeDocument;
import java.io.File;
import java.io.InputStream;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.event.HyperlinkEvent.EventType;

/**
 *
 * @author blitzcoder
 */
public class InfoPanel extends javax.swing.JPanel {

    private static final String template;


    static {
        try {
            InputStream stream = InfoPanel.class.getResourceAsStream("template.html");
            StringBuffer buf = new StringBuffer();
            while (stream.available() != 0) {
                byte[] bytes = new byte[stream.available()];
                stream.read(bytes);
                buf.append(new String(bytes));
            }
            template = buf.toString();
            stream.close();
        } catch (Exception ex) {
            throw new Error(ex);
        }
    }

    /** Creates new form InfoPanel */
    public InfoPanel() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextPane1 = new javax.swing.JTextPane();

        setLayout(new java.awt.GridLayout(1, 0));

        jTextPane1.setContentType("text/html");
        jTextPane1.setEditable(false);
        jTextPane1.addHyperlinkListener(new javax.swing.event.HyperlinkListener() {
            public void hyperlinkUpdate(javax.swing.event.HyperlinkEvent evt) {
                jTextPane1HyperlinkUpdate(evt);
            }
        });
        jScrollPane1.setViewportView(jTextPane1);

        add(jScrollPane1);
    }// </editor-fold>//GEN-END:initComponents

    private void jTextPane1HyperlinkUpdate(javax.swing.event.HyperlinkEvent evt) {//GEN-FIRST:event_jTextPane1HyperlinkUpdate
        if (evt.getEventType().equals(EventType.ACTIVATED)) {
            String type = evt.getDescription().replaceAll("\\:\\/\\/.+", "");
            String value = evt.getDescription().replaceAll(".+\\:\\/\\/", "");

            if (type.equalsIgnoreCase("docobject")) {
                CodeObject obj = findObject(value);
                if (obj != null) {
                    fill(obj);
                }
            } else if (type.equalsIgnoreCase("openfile")) {
                final String[] arr = value.split("@");
                final CodeDocument doc = (CodeDocument)FileOpener.open(new File(arr[0]));
                if (arr.length > 1) {
                    doc.schedule(new Runnable() {
                        public void run() {
                            doc.selectLine(Integer.parseInt(arr[1]));
                        }
                    });
                }
            }

        }
    }//GEN-LAST:event_jTextPane1HyperlinkUpdate

    public CodeObject findObject(String name) {
        ListIterator<Scope> scopeIt = Documentation.scopeList.listIterator();
        while (scopeIt.hasNext()) {
            Scope scope = scopeIt.next();
            ListIterator<Module> modIt = scope.iterateModules();
            while (modIt.hasNext()) {
                Module mod = modIt.next();
                ListIterator<CodeObject> contentIt = mod.iterateContent();
                while (contentIt.hasNext()) {

                    CodeObject obj = contentIt.next();
                    if (obj.getName().equalsIgnoreCase(name)) {
                        return obj;
                    }

                }
            }
        }
        return null;
    }

    public void fill(CodeObject obj) {

        String template = InfoPanel.template;

        String objectType = "";
        if (obj instanceof CodeConstant) {
            objectType = "Constant";
        } else if (obj instanceof CodeField) {
            objectType = "Field";
        } else if (obj instanceof CodeFunction) {
            objectType = "Function";
        } else if (obj instanceof CodeGlobal) {
            objectType = "Global";
        } else if (obj instanceof CodeMethod) {
            objectType = "Method";
        } else if (obj instanceof CodeType) {
            objectType = "Type";
        } else {
            throw new Error("Unknown object type");
        }

        template = template.replace("$title$", objectType + " " + obj.getName());

        if (obj.getModule() != null) {
            template = template.replace("$module$", obj.getModule().getName());
            template = template.replace("$scope$", obj.getModule().getParent().getName());
        } else {
            template = template.replace("$module$", "");
            template = template.replace("$scope$", "");
        }

       
        template = template.replace("$filename$", obj.getFile().getName());
        template = template.replace("$file$", obj.getFile().getAbsolutePath());


        template = template.replace("$line$", obj.getLine() + "");

        if (obj instanceof CodeParameterObject) {
            CodeParameterObject pobj = (CodeParameterObject) obj;
            String params = "";
            ListIterator<CodeParameter> it = pobj.getParameters().listIterator();
            while (it.hasNext()) {
                CodeParameter param = it.next();
                params += "<b>" + param.getName() + "</b>:" + param.getType();
                if (param.getValue().length() != 0) {
                    params += " = " + param.getValue();
                }
                params += "<br>";
            }
            template = template.replace("$params$", params);
        } else {
            template = template.replace("$params$", "");
        }

        template = template.replace("$bbdoc$", convertBBDoc(obj.getBBDoc()));
        template = template.replace("$about$", convertBBDoc(obj.getAbout()));
        template = template.replace("$returns$", convertBBDoc(obj.getReturns()));


        jTextPane1.setText(template);
    }

    private String convertBBDoc(String bbdoc) {

        bbdoc = bbdoc.replace("\n", "<br>");

        Matcher matcher;

        // Replace links to other functions/methods
        // Example:
        // #CreateWindow
        matcher = Pattern.compile("\\#\\w+").matcher(bbdoc);
        while (matcher.find()) {
            String replace = "<a href=\"DocObject://" + matcher.group().substring(1) + "\">" + matcher.group().substring(1) + "</a>";
            bbdoc = bbdoc.replaceFirst(matcher.group(), replace);
        }

        // Replace bold words
        // Example:
        // @IamBold
        matcher = Pattern.compile("\\@\\w+").matcher(bbdoc);
        while (matcher.find()) {
            String replace = "<b>" + matcher.group().substring(1) + "</b>";
            bbdoc = bbdoc.replaceFirst(matcher.group(), replace);
        }

        // Replace italic words
        // Example:
        // %IamItalic
        matcher = Pattern.compile("\\%\\w+").matcher(bbdoc);
        while (matcher.find()) {
            String replace = "<i>" + matcher.group().substring(1) + "</i>";
            bbdoc = bbdoc.replaceFirst(matcher.group(), replace);
        }

        // Replace bold areas
        // Example:
        // @{Event ID}
        matcher = Pattern.compile("\\@\\{[^\\}]+\\}").matcher(bbdoc);
        while (matcher.find()) {
            String replace = "<b>" + matcher.group().substring(2, matcher.group().length() - 1) + "</b>";
            bbdoc = bbdoc.replace(matcher.group(), replace);
        }

        // Replace italic areas
        // Example:
        // %{Event ID}
        matcher = Pattern.compile("\\%\\{[^\\}]+\\}").matcher(bbdoc);
        while (matcher.find()) {
            String replace = "<i>" + matcher.group().substring(2, matcher.group().length() - 1) + "</i>";
            bbdoc = bbdoc.replace(matcher.group(), replace);
        }

        // Replace Tables
        // Tables start with [ and ends with ]
        // * starts a new line
        // | starts a new cell
        matcher = Pattern.compile("\\[[^\\]]+\\]", Pattern.MULTILINE).matcher(bbdoc);
        while (matcher.find()) {
            String replace = matcher.group();
            replace = replace.replace("*", "</td></tr><tr><td>");
            replace = replace.replace("|", "</td><td>");
            bbdoc = bbdoc.replace(matcher.group(), replace);
        }
        bbdoc = bbdoc.replace("[", "<table border=\"1\"><tr><td>");
        bbdoc = bbdoc.replace("]", "</td></tr></table>");

        return bbdoc;

    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextPane jTextPane1;
    // End of variables declaration//GEN-END:variables
}
